<?php
/*
 * Licensed this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distrsibuted under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

  namespace org\boapi\shop;

  include_once (__DIR__ . '/IChecknumber.php');
  include_once (__DIR__ . '/GTIN.php');

/**
 * International Standard Serial Number is a 8 digits number for periodic papers like journals.
 * @author Sebastian Ritter
 * @license Apache License Version 2.0
 * @version 3.0.0.0
 */
final class ISSN implements \org\boapi\core\IChecknumber {
    /**
     * Creates a ISSN Object from GTIN
     * <param name="gtin"></param>
     * @return ISSN instance
     */
    public static function parse ($gtin) {
      if (substr($gtin->getNumber (),0,3) != "977") {
        throw new exception ("GTIN is not an ISSN, because it starts not with 977 ($gtin)");
      }
      // GTIN = 977072486790p => 0724-8679
      $instance = new ISSN ();
      $value = substr ($gtin->getNumber (),3, 8);
      $instance->setCompleteValue ($value);
      $instance->isChecknumberCorrect ();
      $value = substr ($value,0, length($value) - 1) + $instance->getChecknumber ();
      $instance->setCompleteValue ($value);
      return $instance;
    }
    /// <summary>
    /// Set the ISSN
    /// </summary>
    /// <param name="issn"></param>
    public function setCompleteValue ($issn) {
      $nummer ='';
      if (is_array ($issn)) {
      	$issn = $issn [0];
      }
      for ($i = 0; $i < strlen($issn); $i++) {
        $c = substr ($issn, $i, 1);
        if (is_numeric ($c) || $c == 'X') {
          $nummer = $nummer . $c;
        }
        else if ($c != '-') {
          throw new exception ("Illegal character in ISSN  ($issn)");
        }
      }
      
      while (strlen($nummer) < 8) {
        $nummer = '0'.$nummer;
      }
      $this->number = $nummer;
      $this->checknumber = 'R';
    }

    /// <summary>
    /// International Standard Serial Number
    /// </summary>
    private $number;

    /// <summary>
    /// The number of ISSN
    /// </summary>
    /// <returns></returns>
    public function getNumber () {
      return $this->number;
    }

    /// <summary>
    /// The valid checknumber
    /// </summary>
    private $checknumber = 'R';
    /// <summary>
    /// Return the valid checknumber
    /// </summary>
    /// <returns></returns>
    private function getChecknumber () {
      if ($this->checknumber == 'R') {
        $this->isChecknumberCorrect ();
      }
      return $this->checknumber;
    }

    /// <summary>
    /// Is the checknumber correct
    /// </summary>
    /// <returns></returns>
    public function isChecknumberCorrect () {
      $factors = array ( 8, 7, 6, 5, 4, 3, 2 ); // only first seven
      $digits = array(); 
      for ($i = 0; $i < count($factors); $i++) {
        $digits[$i] = substr ($this->number,$i,1);
      }
      $sum = 0;
      for ($i = 0; $i < count($digits); $i++) {
        $sum += $digits[$i] * $factors[$i];
      }
      $mod11 = sum % 11;
      $checkDigit = 11 - mod11;
      switch ($checkDigit) {
        case 10: 
          $this->checknumber = 'X';
          break;
        case 11:
          $this->checknumber = '0';
          break;
        default:
          $this->checknumber = char.Parse (checkDigit);
          break;
      }
      return $this->checknumber == substr($this->number,-1);
    }
  }

?>
